/**
 * Copyright 2000 self.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 *
 * @author Ashin Wimalajeewa
 */
package self.amigo.tool;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JMenu;

import self.amigo.editor.BasicEditor;
import self.amigo.editor.ui.BasicEditingEnvironment;
import self.amigo.module.IEditingEnvironment;
import self.amigo.module.IEditingHost;
import self.amigo.module.IModule;
import self.amigo.module.OpenInfo;
import self.amigo.module.SaveInfo;
import self.gee.IDiagram;
import self.gee.editor.CommandManager;
import self.gee.editor.ICommand;
import self.gee.editor.IEditorListener;

public class AgileModelingShell implements IEditingEnvironment, IEditorListener {
  private AgileModeler            owner;
  private BasicEditingEnvironment gui;
  private BasicEditor             editor;
  private IEditingHost            host;
  private boolean                 loaded  = false;

  private List                    currentSelections = new ArrayList();

  private DiagramManager          diagramManager;
  private UndoManager             undoManager;
  private SelectionManager        selectionManager;
  private ForwardBackManager      forwardBackManager;
  private AlignmentManager        alignmentManager;

  private JMenu                   viewItem;

  public AgileModelingShell( AgileModeler ownr ) {
    owner = ownr;
  }

  void init() {
    if ( loaded )
      return;
    loaded = true;
    gui    = new BasicEditingEnvironment();
    editor = new BasicEditor();
    editor.setEditorListener( this );
    gui.canvas.addEditingListener( editor.getEditingController() );
    editor.prepareToolbar( gui.toolset );
    editor.prepareInspector( gui.inspector );

    undoManager = new UndoManager( editor );
    selectionManager = new SelectionManager( this, editor, currentSelections );
    forwardBackManager = new ForwardBackManager( editor, currentSelections );
    alignmentManager = new AlignmentManager( editor, currentSelections );

    undoManager.initMenus( host );
    selectionManager.initMenus( host );

    gui.setAutoCommitHandler( new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        autoCommit_actionPerformed(e);
      }
    });
  }

  void unmountDiagram() {
    editor.unmount();
    diagramManager.active.diagram.removeCanvas();
    host.setTitle( "" );
  }

  void mountDiagram() {
    diagramManager.active.diagram.prepareSurface( gui.canvas );
    editor.mount( diagramManager.active.diagram );
    host.mount( this );
    currentSelections.clear();
    editor.inspectSelectedObjects( currentSelections );
    gui.canvas.redraw();
    refreshTitle();
  }

  void resetMenuItems( boolean activated ) {
    undoManager.activateMenus( activated );
    selectionManager.activateMenus( activated );
    diagramManager.activateMenus( activated );
    if ( !activated )
      return;
    currentSelections.clear();
    editor.getSelectedElements( currentSelections );
    int selCount = currentSelections.size();
    selectionChanged( currentSelections, selCount ); // update edit menu
    commandExecuted( -1, null, editor.getCommandHistory() );
  }

  // IEditorListener support
  public void selectionChanged( java.util.List elementsInSelection, int count ) {
    currentSelections.clear();
//    editor.getSelectedElements( currentSelections );
//    count = currentSelections.size();
    currentSelections.addAll( elementsInSelection );

    selectionManager.resetMenus( count );
    forwardBackManager.resetMenus( count );
    alignmentManager.resetMenus( count );
  }

  public void commandExecuted( int execType, ICommand cmd, CommandManager history ) {
    undoManager.resetMenus( history );
    refreshTitle();
  }

  // IEditingEnvironment support
  public void     setActive( boolean activated ) {
    resetMenuItems( activated );
  }

  public IModule  getModule() {
    return owner;
  }

  public void     setHost( IEditingHost h ) {
    host = h;
    if ( diagramManager == null )
      diagramManager = new DiagramManager( h, this );
  }

  public void     open( OpenInfo open ) throws IOException {
    diagramManager.open( open );
  }

  public void     getCloseInfos( java.util.List store, boolean activeOnly ) {
    diagramManager.getCloseInfos( store, activeOnly );
  }

  public void     save( OpenInfo open, SaveInfo save ) throws IOException {
    diagramManager.save( open, save );
  }

  public void     close( OpenInfo info ) {
    diagramManager.close( info );
  }

  public void     undo() {
    undoManager.undo();
  }

  public void     redo() {
    undoManager.redo();
  }

  public void     copy() throws IOException {
    selectionManager.copy();
  }

  public void     cut() throws IOException {
    selectionManager.cut();
  }

  public void     paste() throws IOException {
    selectionManager.paste();
  }

  public void     delete() {
    selectionManager.delete();
    resetMenuItems( diagramManager.active != null );
  }

  public void     selectAll() {
    editor.selectAllElements();
  }

  public void     getInstallMenus( java.util.List store ) {
    if ( viewItem == null ) {
      viewItem = new JMenu( "View" );
      viewItem.setMnemonic( 'V' );
      forwardBackManager.installMenus( viewItem );
      viewItem.addSeparator();
      alignmentManager.installMenus( viewItem );
    }
    store.add( viewItem );
  }

  public void     getWindowOpenCommandActions( java.util.List store ) {
    diagramManager.getWindowOpenCommandActions( store );
  }

  public void     getNewCommandActions( java.util.List store ) {
    diagramManager.getNewCommandActions( store );
  }

  public Component toComponent() {
    return gui;
  }

  private void refreshTitle() {
    IDiagram diag = diagramManager.active.diagram;
    String type = diag.getClass().getName();
    int pos = type.lastIndexOf( '.' );
    if ( pos > -1 )
      type = type.substring( pos + 1 );
    host.setTitle( self.io.PathUtils.makePathEndWithSlash(type) + diag.getTitle() );
  }

  private void autoCommit_actionPerformed(ActionEvent e) {
    editor.setAutoCommit( gui.getAutoCommitStatus() );
  }
}